package com.xqboss.apps.service.sys;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.IdUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.write.style.column.LongestMatchColumnWidthStyleStrategy;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xqboss.apps.convert.user.ExportUserNftSourceTypeEnumConverter;
import com.xqboss.apps.convert.user.ExportUserNftStatusEnumConverter;
import com.xqboss.apps.domain.sys.SnapshotCollection;
import com.xqboss.apps.dto.sys.SnapshotDto;
import com.xqboss.apps.enums.nft.NftTypeEnum;
import com.xqboss.apps.enums.sys.FileTypeEnum;
import com.xqboss.apps.mapper.member.SysUserNftMapper;
import com.xqboss.apps.mapper.sys.SnapshotCollectionMapper;
import com.xqboss.apps.service.aliyun.OssService;
import com.xqboss.apps.vo.sys.SnapshotVO;
import com.xqboss.common.core.domain.R;
import com.xqboss.common.exception.ServiceException;
import com.xqboss.common.utils.LocalDateUtils;
import com.xqboss.common.utils.SecurityUtils;
import com.xqboss.system.service.ISysUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.io.ByteArrayOutputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 * 藏品快照接口
 *
 * @author wangcong
 * @date 2023-09-11
 */
@Service
public class SnapshotCollectionService extends ServiceImpl<SnapshotCollectionMapper, SnapshotCollection> {

    @Resource
    private SysUserNftMapper sysUserNftMapper;
    @Autowired
    private OssService ossService;
    @Autowired
    private ISysUserService sysUserService;

    @Transactional(rollbackFor = Exception.class)
    public R create(SnapshotDto dto) {
        if (CollUtil.isEmpty(dto.getNftIds()) && Objects.isNull(dto.getUserId())) {
            return R.fail("藏品和用户不能同时为空");
        }
        String cause = "";
        if (Objects.nonNull(dto.getUserId())) {
            cause = "_" + dto.getUserId() + "_" + sysUserService.selectUserById(dto.getUserId()).getNickName();
        }
        //封装快照记录对象
        SnapshotCollection snapshotCollection = new SnapshotCollection();
        snapshotCollection.setCreateTime(LocalDateUtils.getCurrentLocalDateTime());
        snapshotCollection.setSnapshotCause(dto.getSnapshotCause() + cause);
        snapshotCollection.setUserId(SecurityUtils.getUserId());
        snapshotCollection.setType(dto.getType());
        snapshotCollection.setUserName(SecurityUtils.getUsername());
        //添加到数据库
        this.save(snapshotCollection);

        List<SnapshotVO> res = new ArrayList<>();
        if (CollUtil.isNotEmpty(dto.getNftIds())) {
            // 快照藏品
            dto.getNftIds().forEach(nftId -> {
                if (dto.getType().equals(NftTypeEnum.NORMAL.getValue())
                        || dto.getType().equals(NftTypeEnum.EQUIPMENT.getValue())) {//藏品装备快照
                    List<SnapshotVO> voList = sysUserNftMapper.selectSnapshot(nftId, dto.getUserId());
                    res.addAll(voList);
                } else if (dto.getType().equals(NftTypeEnum.BOX.getValue())) {//箱子快照
                    List<SnapshotVO> voList = sysUserNftMapper.selectSnapshotBox(nftId, dto.getUserId());
                    res.addAll(voList);
                } else {
                    throw new ServiceException("快照类型错误");
                }
            });
        } else {
            // 快照用户背包
            if (dto.getType().equals(NftTypeEnum.NORMAL.getValue())
                    || dto.getType().equals(NftTypeEnum.EQUIPMENT.getValue())) {//用户藏品装备快照
                List<SnapshotVO> voList = sysUserNftMapper.selectSnapshot(null, dto.getUserId());
                res.addAll(voList);
            } else if (dto.getType().equals(NftTypeEnum.BOX.getValue())) {//用户箱子快照
                List<SnapshotVO> voList = sysUserNftMapper.selectSnapshotBox(null, dto.getUserId());
                res.addAll(voList);
            } else {
                throw new ServiceException("快照类型错误");
            }
        }

        if (CollUtil.isNotEmpty(res)) {
            //建立一个字节数组输出流，将excel文件的内容存入其中
            ByteArrayOutputStream os = new ByteArrayOutputStream();
            /**
             *   这里指定用哪个class去写，然后写到第一个sheet，名字为模板，然后文件流会自动关闭
             *   这里可以定义表格的各种样式
             *   out为字节流
             *   clazz为实体类的反射
             */
            EasyExcel.write(os, SnapshotVO.class)
                    .registerWriteHandler(new LongestMatchColumnWidthStyleStrategy())
                    .registerConverter(new ExportUserNftStatusEnumConverter())
                    .registerConverter(new ExportUserNftSourceTypeEnumConverter())
                    .sheet("快照数据").doWrite(res);

            String path = FileTypeEnum.Snapshot.getPath() + IdUtil.fastSimpleUUID() + ".xlsx";
            ossService.fileUpload(os, path);
            snapshotCollection.setUrl(path);
            snapshotCollection.setUpdateTime(LocalDateUtils.getCurrentLocalDateTime());
            //修改 oss的访问路径
            updateById(snapshotCollection);
        } else {
            return R.fail( "宝藏暂无持有者，下载路径暂无");
        }
        return R.ok();
    }
}
